#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
机器人舞蹈控制系统的exe打包脚本
使用PyInstaller将项目打包为Windows可执行文件
"""

import os
import sys
import subprocess
import shutil
from pathlib import Path

def create_spec_file():
    """创建.spec文件用于PyInstaller打包配置"""
    spec_content = '''# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
    ['fluent_ui.py'],
    pathex=[],
    binaries=[],
    datas=[
        ('config.json', '.'),
        ('robot_images/*', 'robot_images'),
    ],
    hiddenimports=[
        'PyQt5.sip',
        'qfluentwidgets',
        'numpy',
        'requests',
        'serial',
        'main_controller',
        'system_state',
        'motion_generator',
        'robot_comm',
        'config_manager',
        'data_control',
        'timeline_editor',
        'music',
        'xfyun_speech',
        'exception_handler',
        'ch',
        'X1_http',
        'ble_notify_debug',
        'test_ble_notify',
        'test_data_control',
        'test_esp32_comm',
        'test_wifi_config',
    ],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='robot_dance_controller',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
'''
    
    with open('robot_dance_controller.spec', 'w', encoding='utf-8') as f:
        f.write(spec_content)
    
    print("已创建打包配置文件 robot_dance_controller.spec")

def install_pyinstaller():
    """安装PyInstaller"""
    try:
        subprocess.check_call([sys.executable, "-m", "pip", "install", "pyinstaller"])
        print("PyInstaller 安装成功")
    except subprocess.CalledProcessError:
        print("PyInstaller 安装失败")
        return False
    return True

def build_executable():
    """构建可执行文件"""
    # 如果存在spec文件，则使用spec文件打包
    if os.path.exists('robot_dance_controller.spec'):
        print("使用spec文件进行打包...")
        cmd = [sys.executable, "-m", "PyInstaller", "--noconfirm", "robot_dance_controller.spec"]
    else:
        print("使用命令行参数进行打包...")
        cmd = [
            sys.executable, "-m", "PyInstaller",
            "--noconfirm",
            "--onedir",
            "--windowed",
            "--name", "robot_dance_controller",
            "--add-data", "config.json;.",
            "--add-data", "robot_images;robot_images",
            "--hidden-import", "PyQt5.sip",
            "--hidden-import", "qfluentwidgets",
            "--hidden-import", "main_controller",
            "--hidden-import", "system_state",
            "--hidden-import", "motion_generator",
            "--hidden-import", "robot_comm",
            "--hidden-import", "config_manager",
            "--hidden-import", "data_control",
            "--hidden-import", "timeline_editor",
            "--hidden-import", "music",
            "--hidden-import", "xfyun_speech",
            "--hidden-import", "exception_handler",
            "fluent_ui.py"
        ]
    
    try:
        print("开始打包，请稍候...")
        print(f"执行命令: {' '.join(cmd)}")
        subprocess.check_call(cmd)
        print("打包完成！")
        return True
    except subprocess.CalledProcessError as e:
        print(f"打包过程中出现错误: {e}")
        return False

def main():
    """主函数"""
    print("机器人舞蹈控制系统打包工具")
    print("=" * 40)
    
    # 安装PyInstaller
    print("检查PyInstaller...")
    if not install_pyinstaller():
        return
    
    # 创建spec文件
    print("创建打包配置文件...")
    create_spec_file()
    
    # 构建可执行文件
    print("开始构建可执行文件...")
    if build_executable():
        print("\\n打包成功！")
        print("可执行文件位于 dist/robot_dance_controller/ 目录下")
        print("\\n你可以将整个 robot_dance_controller 文件夹分发给其他用户")
    else:
        print("\\n打包失败，请检查错误信息")

if __name__ == "__main__":
    main()